﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace nwrole.Azure {
    public class WorkerRoleBase {
        private bool running = false;
        private bool stopped = false;

        private nwrole.lib.SupervisorHost supervisorHost;

        public void Run() {
            Trace.WriteLine("nwrole.Azure.WorkerRoleBase Started", "Information");

            running = true;

            supervisorHost = new nwrole.lib.SupervisorHost(new AzureServiceProvider(), "nwrole.Azure.AzurePluginProvider, nwrole.Azure", 8084);

            supervisorHost.Start();

            while (running) {
                Thread.Sleep(5000);
                Trace.WriteLine("Working", "Information");
            }

            Trace.WriteLine("Stopping", "Information");

            stopped = true;

            supervisorHost.Stop();

            Trace.WriteLine("Stopped", "Information");

            Thread.Sleep(Timeout.Infinite);
        }

        public bool OnStart() {
            Trace.WriteLine("OnStart Begin");

            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => {
                try
                {
                    configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
                }
                catch(Exception e)
                {
                    Trace.WriteLine("OnStart: error getting config value: " + configName);
                    throw e;
                }
            });

            RoleEnvironment.Changing += new EventHandler<RoleEnvironmentChangingEventArgs>(RoleEnvironment_Changing);
            RoleEnvironment.Changed += new EventHandler<RoleEnvironmentChangedEventArgs>(RoleEnvironment_Changed);

            Trace.WriteLine("OnStart Done");

            return true;
        }

        private static readonly string[] ExemptConfigurationItems = new[] { "SupervisorName" };

        void RoleEnvironment_Changing(object sender, RoleEnvironmentChangingEventArgs e) {

            Trace.WriteLine("RoleEnvironment_Changing", "Information");

            Func<RoleEnvironmentConfigurationSettingChange, bool> changeIsExempt = x => !ExemptConfigurationItems.Contains(x.ConfigurationSettingName);

            var environmentChanges = e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>();
            e.Cancel = environmentChanges.Any(changeIsExempt);

            if (!e.Cancel) {
                Trace.WriteLine("RoleEnvironment_Changing no reboot needed", "Information");
                //var oldMultiplier = RoleEnvironment.GetConfigurationSettingValue("SearchMultiplier");
            }
        }

        void RoleEnvironment_Changed(object sender, RoleEnvironmentChangedEventArgs e) {
            /*supervisorHost.Stop();
            var newMultiplier = RoleEnvironment.GetConfigurationSettingValue("SearchMultiplier");
            supervisorHost.Start();*/
        }

        public void OnStop() {
            Trace.WriteLine("OnStop", "Information");

            running = false;

            while (!stopped)
                Thread.Sleep(500);
        }
    }
}
